<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>star & line</title>
  <style>
    body {
      margin: 0;
      height: 100vh;
      background-color: lightblue;
      overflow: hidden;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    #bg {
      position: absolute;
      left: 0;
      top: 0;
      z-index: -1;
    }
    .card {
      width: 300px;
      height: 200px;
      font-size: 28px;
      font-weight: 600;
      background-color: #fff;
      border-radius: 16px;
      box-shadow: 0 2px 16px 2px #00000030;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  </style>
  <script type="module" crossorigin src="./assets/index.935273ac.js"></script>
  </head>
<body>
  <canvas id="bg"></canvas>

  <div class="card">
    Hello World !
  </div>

  <script>
    const canvas = document.querySelector('#bg');

    // 设置大小 不能通过css设置大小
    function setCanvas() {
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
    }

    window.addEventListener('resize', setCanvas);
    setCanvas();

    /**
     * @type {CanvasRenderingContext2D}
     */
    const ctx = canvas.getContext('2d');

    /* @type {{x: number, y: number, speedX: number, speedY: number}[]} */
    const starList = [];
    // 星星数量
    const len = 80;
    // 连线长度
    const lineLength = 70;

    // 初始化星星位置
    for (let i = 0; i < len; i++) {
      const { x, y } = makeCoordinate();
      starList.push({ x, y, speedX: random(0.1, 1.2) - 0.6, speedY: random(0.1, 1.2) - 0.6 });
    }

    function draw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      // 1. 绘制星星
      for (let i = 0; i < len; i++) {
        const { x, y } = starList[i];
        drawStar(x, y);
      }

      // 2. 连线
      for (let i = 0; i < len; i++) {
        const start = starList[i];
        for (let j = i + 1; j < len; j++) {
          const end = starList[j];
          if (Math.abs(start.x - end.x) < lineLength && Math.abs(start.y - end.y) < lineLength) {
            // 连接两点
            drawLine(start, end);
          }
        }

        // 3. 改变星星位置
        start.x += start.speedX;
        if (start.x > canvas.width || start.x < 0) {
          start.speedX = -start.speedX;
        }
        start.y += start.speedY;
        if (start.y > canvas.width || start.y < 0) {
          start.speedY = -start.speedY;
        }
      }

      requestAnimationFrame(draw);
    }

    // 开始动画
    requestAnimationFrame(draw)

    /**
     * 绘制线条
     * @param {{x: number, y: number}} start
     * @param {{x: number, y: number}} end
     */
    function drawLine(start, end) {
      ctx.beginPath();
      ctx.moveTo(start.x, start.y);
      ctx.lineTo(end.x, end.y);
      ctx.strokeStyle = 'lightcyan';
      ctx.stroke();
      ctx.closePath();
    }

    /**
     * 绘制星星
     * @param {number} x
     * @param {number} y
     */
    function drawStar(x, y) {
      ctx.beginPath();
      ctx.arc(x, y, 6, 0, 2 * Math.PI);
      ctx.fillStyle = 'lightcyan';
      ctx.fill();
      ctx.closePath();
    }

    /**
     * 随机坐标
     * @returns {{x: number, y: number}}
     */
    function makeCoordinate() {
      return {
        x: random(0, canvas.width),
        y: random(0, canvas.height),
      }
    }

    /**
     * 随机数
     * @param {number} start
     * @param {number} end
     */
    function random(start, end) {
      return start + Math.random() * (end - start);
    }
  </script>
</body>
</html>
